#include <cubefs/core/tools/types/typelist.hpp>
#include <cubefs/core/tools/types/sublist.hpp>
#include <cubefs/core/tools/types/hierarchy.hpp>

#include <cubefs/core/container/container.hpp>


#include <typeinfo>
#include <iostream>

using namespace std;

using namespace cubefs::core;

using namespace cubefs::core::tools;
using namespace cubefs::core::container;
using namespace cubefs::core::tools::types::typelist;
using namespace cubefs::core::tools::types::hierarchy;


template <typename MyType, typename Types>
class Base1 {
public:
    MyType& me_;

    Base1(MyType& me): me_(me) {
        cout<<"BaseCtr: "<<&me_<<endl;
    }

    void dump() {
        cout<<"Base "<<endl;
        me_.dump1();
        me_.dump2();
    }
};


template <typename T>
class name1{};

template <typename T>
class name2{};

namespace cubefs    {
namespace core      {
namespace container {


template <typename Profile, typename T, typename MyType, typename Base>
class ModelPart<RootProfile, Profile, name1<T>, MyType, Base>: public Base {
    MyType& me_;
public:
    typedef ModelPart<RootProfile, Profile, name1<T>, MyType, Base> Locate;
    
    ModelPart(MyType& me): Base(me), me_(me) {
        cout<<"C1: "<<&me_<<endl;
    }

    void dump1() {
        me_.dump2();
        cout<<"dump1: "<<typeid(T).name()<<endl;
    }
};


template <typename Profile, typename T, typename MyType, typename Base>
class ModelPart<RootProfile, Profile, name2<T>, MyType, Base>: public Base {
    MyType &me_;
public:
    typedef ModelPart<RootProfile, Profile, name2<T>, MyType, Base> Locate;

    ModelPart(MyType &me): Base(me), me_(me)  {}

    void dump2() {
        cout<<"dump2: "<<typeid(T).name()<<endl;
    }
};

/*template <typename Profile, typename T, typename MyType, typename Base>
class Controller<Derived2Profile, Profile, name2<T>, MyType, Base>: public Base {
    MyType &me_;
public:
    typedef Controller<Derived2Profile, Profile, name2<T>, MyType, Base> Locate;

    Controller(MyType &me): Base(me), me_(me)  {
        cout<<"Derived N2C1"<<endl;
    }

    void dump2() {
        cout<<"dump2xcx: "<<typeid(T).name()<<endl;
    }
};
*/


//
//template <typename Profile, typename MyType, typename TypesType, typename Default>
//class TypeFactory<Derived2Profile, Profile, ModelBaseName<MyType, TypesType>, Default>    {
//public:
//    typedef Base1<MyType, TypesType>                                            Type;
//};


}
}
}


class TypesType1{
public:
    //typedef long PageId;
    //typedef long PageMgr;
};

int main() {

    //typedef TypeAwareBuilder<Derived2Profile, Derived2Profile,  TypeListTool<name2<Int>, name1<Long> >::List, TypesType1, ControllerPart, ControllerBaseName> C;
//
//    typedef ModelBuilder<Derived2Profile, TypeListTool<name2<Int>, name1<Long> >::List, TypesType1, ModelBaseName> C;
//
//    typedef TypeContainer<Derived2Profile> TC;
//
//    cout<<typeid(TC).name()<<endl;
//    C c;
//    //c.dump();


    return 0;
}
